package com.webserver.core;


import com.webserver.core.annotations.Controller;
import com.webserver.core.annotations.RequertMapping;

import java.io.File;
import java.lang.reflect.Method;

import java.util.HashMap;
import java.util.Map;

/**
 * 该类用于维护请求路径与对应的业务处理类和方法
 */
public class HandlerMapping {
    /**
     * 保存每个请求路径与对应的业务处理方法
     * key：请求路径
     * value：处理该请求的业务方法
     *
     * 例如：
     * key:/myweb/regUser
     * value:MethodMapping{
     *     Object Controller => UserController的实例
     *     Method method => reg方法
     * }
     */
    private static Map<String,MethodMapping> mapping=new HashMap<>();

    static {
        try {
            initMapping();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    private static void initMapping() throws Exception {
        /*
        1.扫描com.webserver.controller包下的所有类
        2.利用反射机制加载这些类的类对象
        3.判断该类是否使用注解@Controller标注，没有的则忽略
        4.扫描该类中所有的方法，并判断该方法是否使用注解@RequestMapping标注，没有的忽略
        5.将注解@RequestMapping中参数获取到(该方法对应的请求路径)作为key
        实例化当前Collection并和当前方法对象(Method对象)组成一个MethodMapping作为value存入到mapping这个Map
         */

        File file=new File(HandlerMapping.class.getClassLoader().getResource("./com/webserver/controller").toURI());
        File[]files=file.listFiles(e->e.getName().endsWith("class"));
        for (File f:files){
            String className=f.getName().substring(0,f.getName().indexOf("."));
            Class cls=Class.forName("com.webserver.controller"+className);
            //判断是否又注解@Controller
            if (cls.isAnnotationPresent(Controller.class)){
                //实例化这个Controller
                Object obj=cls.newInstance();
                //获取所有方法
                Method[]methods=cls.getDeclaredMethods();
                for (Method method:methods){
                    //是否有注解@RequestMapping
                    if (method.isAnnotationPresent(RequertMapping.class)){
                        //获取该方法对应的请求路径
                        RequertMapping rm=method.getAnnotation(RequertMapping.class);
                        String key=rm.value();
                        MethodMapping value=new MethodMapping(obj,method);
                        mapping.put(key,value);
                    }
                }
            }


        }
        System.out.println(mapping);
    }

    /**
     * 根据给给定的请求路径获取处理该路径的处理业务
     * @param path
     * @return
     */
    public static MethodMapping getMethod(String path){
        return mapping.get(path);
}

    /**
     * 当前类的每一个实例用于记录一个业务方法以及该方法所属的Controller对象
     */
    public static class MethodMapping{
        private Object controller;
        private Method method;

        public MethodMapping(Object controller, Method method) {
            this.controller = controller;
            this.method = method;
        }

        public Object getController() {
            return controller;
        }

        public void setController(Object controller) {
            this.controller = controller;
        }

        public Method getMethod() {
            return method;
        }

        public void setMethod(Method method) {
          this.method = method;
        }
    }

    public static void main(String[] args) {

    }
}
